package server.console.groups.setting

import com.alee.extended.list.CheckBoxListModel
import com.alee.extended.list.WebCheckBoxList
import com.alee.extended.panel.GroupPanel
import com.alee.extended.panel.GroupingType
import com.alee.laf.button.WebButton
import com.alee.laf.label.WebLabel
import com.alee.laf.list.WebList
import com.alee.laf.menu.WebMenuItem
import com.alee.laf.menu.WebPopupMenu
import com.alee.laf.optionpane.WebOptionPane
import com.alee.laf.panel.WebPanel
import com.alee.laf.rootpane.WebDialog
import com.alee.laf.scroll.WebScrollPane
import com.alee.laf.table.WebTable
import com.alee.laf.text.WebTextField
import com.fasterxml.jackson.core.type.TypeReference
import configs.CubeConfig
import constants.GameConstants
import server.MapleItemInformationProvider
import tools.JsonUtil
import tools.StringUtil
import java.awt.Color
import java.awt.Component
import java.awt.event.FocusAdapter
import java.awt.event.FocusEvent
import java.awt.event.KeyAdapter
import java.awt.event.KeyEvent
import java.io.UnsupportedEncodingException
import java.util.*
import java.util.stream.Collectors
import javax.swing.DefaultListModel
import javax.swing.JTable
import javax.swing.ListSelectionModel
import javax.swing.event.ListDataEvent
import javax.swing.event.ListDataListener
import javax.swing.table.DefaultTableModel
import kotlin.collections.HashMap

class CubeConfigGroup(owner: ConfigPanel) : AbstractConfigGroup(owner, "潜能&魔方管理") {

    private var currSelectedIndex = -1
    private val tableName by lazy {
        val vector = Vector<String>()
        vector.add("类型")
        vector.add("数量")
        vector
    }
    private val gradeList by lazy { arrayListOf("B级", "A级", "S级", "SS级") }
    private val statistics by lazy {
        val hashMap = HashMap<Int, HashMap<Int, Int>>()
        for (i in 0..gradeList.size) {
            hashMap.put(i, HashMap())
        }
        hashMap
    }
    private val statisticsButton by lazy {
        object : WebButton("统计信息") {
            init {
                preferredHeight = 50
                addActionListener { _ ->
                    val dialog = WebDialog(owner, text, true)
                    val groupPanel = GroupPanel(5, false)
                    groupPanel.preferredWidth = 250
                    val vs = Vector<Vector<String>>()
                    statistics[currSelectedIndex]?.forEach { t, u ->
                        val data = Vector<String>()
                        data.add(getType(t))
                        data.add(u.toString())
                        vs.add(data)
                    }
                    val tableModel = DefaultTableModel(vs, tableName)
                    val webTable = WebTable(tableModel)
                    webTable.isEditable = false
                    webTable.autoResizeMode = JTable.AUTO_RESIZE_ALL_COLUMNS
                    webTable.gridColor = Color.LIGHT_GRAY
                    groupPanel.add(WebScrollPane(webTable))
                    groupPanel.add(object : WebButton("确定") {
                        init {
                            addActionListener { dialog.dispose() }
                        }
                    })
                    dialog.add(groupPanel)
                    dialog.pack()
                    dialog.setLocationRelativeTo(this)
                    dialog.isVisible = true
                }
            }
        }
    }
    private val allPotentialIDs: TreeSet<PotentialInfo> by lazy {
        val treeSet = TreeSet<PotentialInfo>(Comparator { o1, o2 -> o1.id.compareTo(o2.id) })
        treeSet.addAll(MapleItemInformationProvider.getInstance().allPotentialIDandName.entries.parallelStream().map {
            val potentialInfo = PotentialInfo(it.key, it.value.left, it.value.right)
            updateStatistics(it.key, it.value.right)
            potentialInfo
        }.collect(Collectors.toSet()))
        treeSet
    }
    private val filterList by lazy {
        val hashSet = object : TreeSet<Int>() {
            override fun toString(): String {
                val it = iterator()
                if (!it.hasNext())
                    return ""

                val sb = StringBuilder()
                while (true) {
                    val e = it.next()
                    sb.append(e)
                    if (!it.hasNext())
                        return sb.toString()
                    sb.append(',').append(' ')
                }
            }
        }
        if (CubeConfig.FILTER_LIST.isNotEmpty()) {
            CubeConfig.FILTER_LIST.replace(" ", "").split(",").forEach { hashSet.add(it.toInt()) }
        }
        hashSet
    }
    private val filterListModel: HashMap<Int, CheckBoxListModel> = HashMap()


    override fun getPreview(): Component {
        val filterCheckBox = WebCheckBoxList()
        val filter = TitleWebPanel("潜能过滤列表(打勾为启用,反之为过滤,过滤后的潜能不会被任何魔方洗出来)")
        filter.preferredHeight = 300

        val gradeListControl = object : WebList(gradeList) {
            init {
                preferredWidth = 100
                selectionMode = ListSelectionModel.SINGLE_SELECTION
                addListSelectionListener { _ ->
                    currSelectedIndex = selectedIndex
                    filterCheckBox.model = filterListModel.computeIfAbsent(selectedIndex, {
                        val newModel = CheckBoxListModel()
                        allPotentialIDs.filter {
                            val stat = GameConstants.getPotentialStats(it.id) - 17
                            stat == selectedIndex && stat >= 0
                        }.forEach { newModel.addCheckBoxElement(it, isFilterPotential(it.id).not()) }

                        newModel.addListDataListener(object : ListDataListener {
                            override fun contentsChanged(e: ListDataEvent?) {
                                val index0 = e?.index0 ?: -1
                                val source = e?.source as CheckBoxListModel
                                val potentialInfo = source.get(index0).userObject as PotentialInfo
                                val isfilter = !source.isCheckBoxSelected(index0)
                                updateStatistics(potentialInfo.id, potentialInfo.type, !isfilter)
//                                println(statistics)
                                if (canFilterOp()) {
                                    source.setCheckBoxSelected(index0, true)
                                    WebOptionPane.showMessageDialog(owner, "请确保每个类型的潜能都至少有一条")
                                    statisticsButton.doClick()
                                    return
                                }
                                if (isfilter) {
                                    filterList.add(potentialInfo.id)
                                } else {
                                    filterList.remove(potentialInfo.id)
                                }
                                CubeConfig.FILTER_LIST = filterList.toString()
                                owner.changeSettingQueue.put("filter.list", CubeConfig.FILTER_LIST)
                                owner.webButtonApply.isEnabled = true
                            }

                            override fun intervalRemoved(e: ListDataEvent?) {
                            }

                            override fun intervalAdded(e: ListDataEvent?) {
                            }
                        })
                        newModel
                    })
                }
            }
        }


        filterCheckBox.componentPopupMenu = object : WebPopupMenu() {
            init {
                add(object : WebMenuItem("全选") {
                    init {
                        addActionListener { _ ->
                            for (i in 0 until filterCheckBox.checkBoxListModel.size()) {
                                filterCheckBox.setCheckBoxSelected(i, true)
                            }
                        }
                    }
                })
            }
        }
        gradeListControl.selectedIndex = 0

        filter.add(GroupPanel(GroupingType.fillLast, 5, GroupPanel(GroupingType.fillFirst, 5, false, WebScrollPane(gradeListControl), statisticsButton), WebScrollPane(filterCheckBox)).setMargin(5))

        return GroupPanel(GroupingType.fillLast, 5, false, filter, CubeChanceGroup())
    }


    /**
     * 魔方概率更改
     */
    inner class CubeChanceGroup : WebPanel() {
        private var currselect = -1
        private var cubeid = 0
        private val gradeLabel by lazy {
            val list = TreeMap<Int, Pair<String, WebTextField>>()
            for (i in 1 until gradeList.size) {
                list.put(i, Pair("${gradeList[i - 1]}->${gradeList[i]}", object : WebTextField(5) {
                    init {
                        addKeyListener(object : KeyAdapter() {
                            override fun keyTyped(e: KeyEvent?) {
                                val keyChar = e?.keyChar

                                if (text.length < 4 && keyChar != null && !e.isControlDown) {
                                    if (keyChar >= KeyEvent.VK_0.toChar() && keyChar <= KeyEvent.VK_9.toChar() || keyChar == KeyEvent.VK_BACK_SPACE.toChar()) {
                                        owner.webButtonApply.isEnabled = true
                                        return
                                    }
                                }
                                e?.consume() //关键，屏蔽掉非法输入
                            }
                        })
                        addFocusListener(object : FocusAdapter() {
                            override fun focusLost(e: FocusEvent?) {
                                if (!StringUtil.isNumber(text)) {
                                    WebOptionPane.showMessageDialog(this@CubeChanceGroup, "只能输入数字！")
                                    return
                                }
                                text = if (text.isEmpty()) "0" else text
                                chanceData[cubeid]?.set(i, text.toInt())
                                CubeConfig.CHANCE_DATA = JsonUtil.getMapperInstance().writeValueAsString(chanceData)
                                owner.changeSettingQueue.put("chance.data", CubeConfig.CHANCE_DATA)
                                owner.webButtonApply.isEnabled = true
                                CubeConfig.updateChanceData()
//                                println("cubeid: $cubeid  index: $i  text: $text  value:${chanceData[cubeid]!![i]}")
                            }
                        })
                    }
                }))
            }
            list
        }
        private val cubeList by lazy {
            object : TreeMap<Int, String>() {
                init {
                    put(0, "默认")
                    put(5062000, "神奇魔方")
                    put(5062001, "混沌神奇魔方")
                    put(5062002, "高级神奇魔方")
                    put(5062005, "惊人的神奇魔方")
                    put(5062006, "白金神奇魔方")
                    put(5062009, "超级神奇魔方")
                    put(5062010, "终极神奇魔方")
                    put(5062090, "记忆魔方")
                    put(5062100, "枫叶魔方")
                    put(5062103, "梦幻的神奇魔方")
                    put(5062500, "大师附加神奇魔方")
                    put(5062501, "[MS特价]潜能变化魔方")
                    put(5062503, "附加潜能记忆魔方")
                    put(5062024, "闪炫魔方")
                    put(5062502, "新春潜能变化魔方")
                }
            }
        }
        private val chanceData by lazy {
            JsonUtil.getMapperInstance().readValue<HashMap<Int, HashMap<Int, Int>>>(CubeConfig.CHANCE_DATA, object : TypeReference<HashMap<Int, HashMap<Int, Int>>>() {})
        }

        init {
            val cube = TitleWebPanel("魔方概率更改")
            val cubePropPanel = GroupPanel(5, false)
            gradeLabel.forEach {
                cubePropPanel.add(GroupPanel(5, WebLabel("${it.value.first}: ").setPreferredWidth(70), it.value.second, WebLabel("%")))
            }
            val cubeListControl = object : WebList() {
                init {
                    preferredWidth = 215
                    selectionMode = ListSelectionModel.SINGLE_SELECTION
                    val defaultListModel = DefaultListModel<Any>()
                    cubeList.forEach { t, u -> defaultListModel.addElement("$u ($t)") }
                    model = defaultListModel
                    addListSelectionListener { e ->
                        if (e.valueIsAdjusting) {
                            cubeid = cubeList.keys.elementAt(selectedIndex)
                            currselect = selectedIndex
                            gradeLabel.forEach { t, u -> u.second.text = chanceData[cubeid]?.get(t).toString() }
                        }
                    }
                }
            }
            cube.add(GroupPanel(GroupingType.fillLast, 5, WebScrollPane(cubeListControl), cubePropPanel).setMargin(5))
            this.add(cube)
        }

    }

    /**
     * 这个函数的功能是帮我查询某个ID是否过滤
     *
     * id 潜能的ID
     */
    private fun isFilterPotential(id: Int): Boolean = filterList.contains(id)


    fun getType(type: Int): String = when (type) {
        10 -> "武器"
        11 -> "所有盔甲"
        20 -> "盾牌"
        21 -> "宠物装备"
        40 -> "配饰"
        51 -> "帽子"
        52 -> "披风"
        53 -> "上衣/裤裙/套服"
        54 -> "手套"
        55 -> "鞋子"
        90 -> "不可用"
        else -> "通用"
    }

    private fun updateStatistics(id: Int, type: Int, add: Boolean = true) {
        val grade = GameConstants.getPotentialStats(id) - 17
        val hashMap = statistics[grade] ?: HashMap()
        val num = hashMap[type] ?: 0
        hashMap.put(type, num + (if (add) 1 else -1))
    }

    private fun canFilterOp(): Boolean = statistics[currSelectedIndex]?.values?.contains(0) ?: false
}


data class PotentialInfo(val id: Int, val name: String, val type: Int) {
    override fun toString(): String = "ID: ${subString(id.toString(), 10)}  最高属性: $name"
}

private fun subString(value: String, max: Int): String {
    var string = value
    try {
        for (i in string.toByteArray(charset("gb2312")).size until max) {
            string += " "
        }
    } catch (e: UnsupportedEncodingException) {
        e.printStackTrace()
    }

    return string
}